package com.xhwl.centiotdata.suppliersystem.eesd.bes;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.pojo.dto.eesd.EesdConfigDTO;
import com.xhwl.centiotdata.service.cent.IEesdCentService;
import com.xhwl.centiotdata.utils.HttpUtils;
import com.xhwl.common.dto.cent.energy.EesdElectricDetailDTO;
import com.xhwl.common.dto.cent.energy.EesdElectricDetailDTO.ValueEntity;
import com.xhwl.common.enums.device.DeviceTypeEnum;
import com.xhwl.common.exception.BusinessException;
import com.xhwl.common.vo.cent.eesd.DeviceHandleVO;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class BesApiHandler {
	@Autowired
	IEesdCentService iEesdCentService;
	
	public void pullBaDevice(EesdConfigDTO eesdConfigDTO) {
		try {
			eesdConfigDTO.setToken(null);
			getBesToken(eesdConfigDTO);
			JSONArray electricDevices = getElectricDevices(eesdConfigDTO);
			List<String> deviceCodeList = new ArrayList<>();
			if (electricDevices != null && !electricDevices.isEmpty()) {
				List<DeviceHandleVO> deviceList = new ArrayList<>();
				for (Object obj : electricDevices) {
					JSONObject e = (JSONObject) obj;
//					0: "电表"
//					1: "水表"
					if(!"0".equals(e.getString("type"))) {
						continue;
					}
					String code = e.getString("code");
					if (eesdConfigDTO.getOnlyConfigDevices() == null || eesdConfigDTO.getOnlyConfigDevices().contains(code)) {
						deviceCodeList.add(code);
						deviceList.add(fillDeviceDetail(eesdConfigDTO.getProjectId(), e));
					}
					
				}
				if(CollectionUtils.isNotEmpty(deviceList)) {
					iEesdCentService.deviceHandleSync(deviceList);
				}
			}
			if(CollectionUtils.isNotEmpty(deviceCodeList)) {
				JSONArray electricDevicesReads = getElectricDevicesRead(eesdConfigDTO, deviceCodeList);
				if(electricDevicesReads != null && !electricDevicesReads.isEmpty()) {
					List<EesdElectricDetailDTO> electricList = new ArrayList<>();
					for (Object obj : electricDevicesReads) {
						JSONObject e = (JSONObject) obj;
						electricList.add(parseElectric(eesdConfigDTO.getProjectId(), e));
					}
					if(CollectionUtils.isNotEmpty(electricList)) {
						iEesdCentService.baDeviceDetailSync(electricList);
					}
				}
			}
		} catch (Exception e) {
			log.error("拉取BES设备系统异常", e);
		}
	}

	private DeviceHandleVO fillDeviceDetail(Integer projectId, JSONObject objJson) {
		DeviceHandleVO vo = new DeviceHandleVO();
		vo.setProjectId(projectId);
		vo.setDeviceType(DeviceTypeEnum.WATT_HOUR_METER.getCode());
		vo.setDeviceNo(objJson.getString("code"));
		vo.setDeviceAddress(null);
		vo.setDeviceName(objJson.getString("alias"));
		vo.setDeviceActiveTime(new Date());
		vo.setDevicePosition(null);
		vo.setDeviceCategory(3);
		vo.setDeviceNature(null);
		vo.setDeviceBrand(null);
		vo.setDevicePurpose(null);
		vo.setDeviceModel(null);
		vo.setCountAreas(new ArrayList<>());
//		vo.setenantIds
//		vo.setTenantNames
		vo.setDeviceMeteringAreaType(null);
		vo.setDeviceRange(null);
		vo.setDeviceRate(1.0D);
		vo.setDeviceDate(null);
		vo.setDeviceDesc(null);
		return vo;
	}

	
	private EesdElectricDetailDTO parseElectric(Integer projectId, JSONObject objJson) {
		EesdElectricDetailDTO dto = new EesdElectricDetailDTO();
		dto.setProjectId(projectId);
		dto.setDeviceId(objJson.getString("F_DBSYS_NAME"));
		dto.setTime(new Date());
		dto.setRate(1.0);
		dto.setDeviceType(DeviceTypeEnum.WATT_HOUR_METER.getCode());
		dto.setJsonFieldFlag(false);
		ValueEntity value = new EesdElectricDetailDTO.ValueEntity();
		String data = objJson.getString("F_DATA");
		value.setValue(isNumber(data)?new BigDecimal(data).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue():0.0);
		dto.setValue(value);
		return dto;
	}
	
	/**
     * 通过正则表达式判断字符串是否为数字
     * @param str
     * @return
     */
	private static Pattern pattern = Pattern.compile("^(\\-|\\+)?\\d+(\\.\\d+)?$");
    private boolean isNumber(String str) {
    	if(StringUtils.isBlank(str)) {
    		return false;
    	}
        Matcher m = pattern.matcher(str);
        return m.matches();
    }
	
	/**
	 * 获取bes Token
	 * 
	 * @param eesdConfigDTO
	 * @return
	 * @throws Exception
	 */
	private void getBesToken(EesdConfigDTO eesdConfigDTO) throws Exception {
		Map<String, String> bodys = new HashMap<String, String>();
		bodys.put("uName", eesdConfigDTO.getLoginName());
		bodys.put("uPwd", eesdConfigDTO.getPassword());
		Map<String, String> headers = new HashMap<String, String>();
		headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
		HttpResponse response = HttpUtils.doPost(eesdConfigDTO.getHost(), "/BESWebapp/issp/v1.0/login", null, headers,
				new HashMap<String, String>(), bodys);
		if (200 != response.getStatusLine().getStatusCode()) {
			throw new BusinessException("请求第三方系统异常:code=" + response.getStatusLine().getStatusCode());
		}
		HttpEntity resEntity = response.getEntity();
		if (resEntity != null) {
			String res = EntityUtils.toString(resEntity, "UTF-8");
			JSONObject jsonObject = JSON.parseObject(res);
			if (jsonObject != null && "success".equals(jsonObject.getString("status"))) {
				eesdConfigDTO.setToken(jsonObject.getString("token"));
			}
		}
	}

	/**
	 * { "data" : { "data" : [ { "alias" : "换热站", "code" : "GTHJ020", "type" : "0",
	 * "typeName" : "电表" } ], "status" : "1" } }
	 * 
	 * @param eesdConfigDTO
	 * @return
	 * @throws Exception
	 */
	private JSONArray getElectricDevices(EesdConfigDTO eesdConfigDTO) throws Exception {
		Map<String, String> headers = new HashMap<String, String>();
		headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
		headers.put("Cookie", "JSESSIONID=" + eesdConfigDTO.getToken());
		HttpResponse response = HttpUtils.doGet(eesdConfigDTO.getHost(), "/BESWebapp/api/public/ammeterInfo", null,
				headers, new HashMap<String, String>());
		if (200 != response.getStatusLine().getStatusCode()) {
			throw new BusinessException("请求第三方系统异常:code=" + response.getStatusLine().getStatusCode());
		}
		HttpEntity resEntity = response.getEntity();
		if (resEntity != null) {
			String res = EntityUtils.toString(resEntity, "UTF-8");
			log.info("查询山东高速能耗设备列表:res{}", res);
			JSONObject jsonObject = JSON.parseObject(res);
			if (jsonObject != null) {
				JSONObject jsonData = jsonObject.getJSONObject("data");
				if (jsonData != null && "1".equals(jsonData.getString("status"))) {
					return jsonData.getJSONArray("data");
				}
				
			}
		}
		return null;
	}

	/**
	 * { "data": { "status": "1", "map": { "F_DBSYS_NAME": "GTHJ068", "F_CJSJ":
	 * "2022-07-05 10:46:15", "F_DATA": 29.4 } } }
	 * 
	 * @param eesdConfigDTO
	 * @return
	 * @throws Exception
	 */
	private JSONArray getElectricDevicesRead(EesdConfigDTO eesdConfigDTO, List<String> deviceCodeList) throws Exception {
		Map<String, String> bodys = new HashMap<String, String>();
		bodys.put("ammeterName", deviceCodeList.stream().collect(Collectors.joining(",")));
		Map<String, String> headers = new HashMap<String, String>();
		headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
		headers.put("Cookie", "JSESSIONID=" + eesdConfigDTO.getToken());
		HttpResponse response = HttpUtils.doPost(eesdConfigDTO.getHost(),
				"/BESWebapp/api/public/ammeterRealTimeDataInfo", null, headers, new HashMap<String, String>(), bodys);
		if (200 != response.getStatusLine().getStatusCode()) {
			throw new BusinessException("请求第三方系统异常:code=" + response.getStatusLine().getStatusCode());
		}
		HttpEntity resEntity = response.getEntity();
		if (resEntity != null) {
			String res = EntityUtils.toString(resEntity, "UTF-8");
			log.info("查询山东高速能耗设备读数列表: res{}", res);
			JSONObject jsonObject = JSON.parseObject(res);
			if (jsonObject != null) {
				JSONObject jsonData = jsonObject.getJSONObject("data");
				if (jsonData != null && "1".equals(jsonData.getString("status"))) {
					return jsonData.getJSONArray("list");
				}
			}
		}
		return null;
	}

}
